package com.kun.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.text.replacer.StrReplacer;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.kun.common.Constants;
import com.kun.common.Result;
import com.kun.entity.Attachment;
import com.kun.exception.MyServiceException;
import com.kun.service.AttachmentServiceImpl;
import com.kun.utils.FileUtils;
import com.sun.corba.se.spi.ior.ObjectKey;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.server.PathParam;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/file")
public class AttachmentController {

    @Autowired
    private AttachmentServiceImpl attachmentService;

    @Value("${files.upload.path}")
    private String uploadPath;

    @Value("${server.hostIp}")
    private String hostIp;

    @GetMapping("/deleteFile")
    @ApiOperation("删除指定文件")
    @ResponseBody
    public Result deleteFile(@RequestParam("id")int id){
        Map<String, Object> map = new HashMap<>();
        map.put("id",id);
        List<Attachment> attachments = attachmentService.selectAllAttachments(map);
        if (attachments.size()>1){
            throw new MyServiceException(Constants.CODE_600,"数据库存在相同id的数据");
        }
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("changeDelete",true);
        attachments.get(0).setIsDelete(true);
        attachmentService.updateAttachment(attachments.get(0),hashMap);
        return  Result.success();
    }

    @PostMapping("/batchDeleteFile")
    @ApiOperation("批量删除文件")
    @ResponseBody
    public Result batchDeleteFile(@RequestBody List<Integer> ids){
        for (Integer id : ids) {
            this.deleteFile(id);
        }
        return  Result.success();
    }


    @GetMapping("/queryAllFiles")
    @ApiOperation("查询所有的文件")
    @ResponseBody
    public Result queryAllFiles(@ApiParam("当前页数") @RequestParam("pageIndex")int pageIndex,
                                @ApiParam("页面大小") @RequestParam("pageSize") int pageSize,
                                @ApiParam("文件名") @RequestParam(value = "fileName",required = false) String fileName){
        HashMap<String, Object> map = new HashMap<>();
        map.put("pageIndex",pageIndex);
        map.put("pageSize",pageSize);
        map.put("fileName_like",fileName);

        List<Attachment> attachments = attachmentService.selectAllAttachments(map);
        return  Result.success(attachments);
    }

    @GetMapping("/queryAllFilesNum")
    @ApiOperation("查询文件总数")
    @ResponseBody
    public Result queryAllFilesNum(@ApiParam("文件名") @RequestParam(value = "fileName",required = false) String fileName){
        HashMap<String, Object> map = new HashMap<>();
        map.put("showDelete",false);
        map.put("fileName_like",fileName);
        List<Attachment> attachments = attachmentService.selectAllAttachments(map);
        return  Result.success(attachments.size());
    }

    @GetMapping("/editFileState")
    @ApiOperation("编辑文件启用信息")
    @ResponseBody
    public Result editFileState(@RequestParam("id") Integer id){

        HashMap<String, Integer> map = new HashMap<>();
        map.put("id",id);
        List<Attachment> attachments = attachmentService.selectAllAttachments(map);
        if (attachments.size()>1){
            throw new MyServiceException(Constants.CODE_600,"数据库包含重复id的文件");
        }else{
            attachments.get(0).setEnable(!attachments.get(0).getEnable());
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("changeEnable",true);
            attachmentService.updateAttachment(attachments.get(0),hashMap);
            return  Result.success();
        }

    }

    @PostMapping("/editFile")
    @ApiOperation("编辑文件信息")
    @ResponseBody
    public Result editFile(@RequestBody Attachment attachment){
        Attachment newAttachment = new Attachment();
        newAttachment.setName(attachment.getName());
        newAttachment.setId(attachment.getId());
        HashMap<String, Object> map = new HashMap<>();
        attachmentService.updateAttachment(newAttachment,map);
        return Result.success();
    }



    @PostMapping("/upload")
    @ApiOperation("上传文件")
    @ResponseBody
    public String upload(@RequestParam("file")MultipartFile file) throws IOException {
//        1. 获得原始名字
        String originalFilename = file.getOriginalFilename();
//        2. 获取文件类型
        String type = FileNameUtil.extName(originalFilename);
//        3. 获取文件大小,单位kb
        long size = file.getSize() / 1024;
//        4. 磁盘位置判断，判断该目录是否存在，不存在则重新创建
        File uploadParentPath = new File(uploadPath);
        if (!uploadParentPath.exists()){
            uploadParentPath.mkdirs();
        }
//        5. 生成md5
        File file1 = FileUtils.toFile(file);
        String md5 = SecureUtil.md5(file1);
        File file2 = new File(file1.toURI());
        if (file2.delete()){
            System.out.println("删除成功");
        }else {
            System.out.println("删除失败");
        }

        String url="";

//        6. 判断md5是否存在，若存在，则不进行文件存储；反之，存储文件
        HashMap<String, String> map = new HashMap<>();
        map.put("fileMd5",md5);
        List<Attachment> attachments = attachmentService.selectAllAttachments(map);
        if (attachments.size()>0){
            url=attachments.get(0).getUrl();
        }else{
            String currentFileName = IdUtil.fastSimpleUUID();
            File currentFile = new File(uploadPath + currentFileName +"."+ type);
            file.transferTo(currentFile);
            url="http://"+hostIp+":9090/file/download/"+currentFileName+"."+ type;
        }

        Attachment attachment = new Attachment();
        attachment.setName(originalFilename);
        attachment.setSize(size);
        attachment.setType(type);
        attachment.setUrl(url);
        attachment.setFileMd5(md5);
        attachmentService.addAttachment(attachment);
        return url;
    }


    @GetMapping("/download/{fileName}")
    @ApiOperation("下载文件")
    @ResponseBody
    public String download(@PathVariable("fileName") String fileName,
                           HttpServletResponse response) throws IOException {
//        1. 通过response获得outputStream
        ServletOutputStream outputStream = response.getOutputStream();

//        2. 通过outputStream设置响应头和类型
        HashMap<String, String> map = new HashMap<>();
        map.put("url_like",fileName);
        List<Attachment> attachments = attachmentService.selectAllAttachments(map);
        response.addHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(attachments.get(0).getName(),"UTF-8"));
        response.setContentType("application/octet-stream");

//        3. 通过flush方法进行下载
        File file = new File(uploadPath + fileName);
        outputStream.write(FileUtil.readBytes(file));
        outputStream.flush();
        outputStream.close();
        return "true";

    }





}
